package com.gopay.cashier.web.controller.scan;

import com.alibaba.fastjson.JSONObject;
import com.gopay.cashier.web.command.ScanPayCommand;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.trans.PayChannel;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 扫码支付
 * @author dongdh
 * @2016/8/9 10:30  www.gopay.com.cn Inc.All rights reserved.
 */

@RequestMapping(value = "/scan")
@Controller
public class ScanPayChannelController extends ScanPayBaseController {

    /**
     * 跳转到扫码支付页面
     * @return
     */
    @RequestMapping("/toPay")
    public ModelAndView toScanPay(ScanPayCommand command) throws GopayException {

        //"/00100/content/scan/pay"
        ModelAndView mv = new ModelAndView();

        //查询订单 -- 判断状态 -- 其他校验  校验方案等   //处理登录状态
        String orderId = getRequest().getParameter(GOPAY_ORDER_ID);
        String orderKey = getRequest().getParameter(GOPAY_ORDER_KEY);
        CpsGenMainOrder order = getMainOrder(orderId, true);

        printRequest();

        validate(order, command, false);

        mv.addObject(GOPAY_ORDER_ID, orderId);
        mv.addObject(GOPAY_ORDER_KEY, orderKey);
        mv.addObject("bankCode", command.getBankCode());

        //清算渠道 方案校验
        checkSolution(order, command);

        //防钓鱼校验
        ModelAndView check = checkAntiPhish(command,"/scan/toPay.shtml?orderKey="+getRequest().getParameter("orderKey")+"&orderId="+orderId);
        if(check != null) {
            return check;
        }


        long timeout = expiredTime;

        //判断订单 是否有生成过二维码
        if (PayChannel._16.value.equals(order.getPayChannel()) && StringUtils.isNotBlank(order.getRemark2())) {
            ///有paychannel 和url 说明生成过
            timeout = makeScanUrlRepeat(order, command);
        } else {
            makeScanUrl(order, command);
            timeout = expiredTime;
        }

        //风控校验
        order = getMainOrder(orderId, true);
        riskControlCheck(order);

        logger.error("剩余超时时间  timeout==" + timeout);
        //设置剩余过期 时间
        getRequest().getSession().setAttribute("timeout", timeout);
        mv.addObject("order", getOrderInfo(orderId));
        mv.addObject("qrCode", order.getRemark2());

        render(mv, command);

        return mv;
    }

    /**
     * 根据bankCode做 扫码页面跳转
     * @param mv
     * @param command
     * @throws GopayException
     */
    private void render(ModelAndView mv, ScanPayCommand command) throws GopayException {
        if(BankConstants.BANK_LOGO_ALIPAY.equals(command.getBankCode())){
            mv.setViewName("/00100/content/scan/alipay");
        }else if(BankConstants.BANK_LOGO_WECHAT.equals(command.getBankCode())){
            mv.setViewName("/00100/content/scan/wechatPay");
        }else{
            logger.error("不支持的bankCode=" + command.getBankCode());
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E9002);
        }
    }
    /**
     * 刷新二维码
     */
    @RequestMapping("/refreshCode")
    @ResponseBody
    public String refreshCode(ScanPayCommand command) throws GopayException {

        JSONObject json = new JSONObject();
        //1 成功
        json.put("result", "1");
        try {
            String orderId = getRequest().getParameter(GOPAY_ORDER_ID);
            String orderKey = getRequest().getParameter(GOPAY_ORDER_KEY);
            CpsGenMainOrder order = getMainOrder(orderId, true);

            printRequest();

            //add by zhaojt 判断扫码订单是否过期
            Object date = getRequest().getSession().getAttribute(ORDER_EXPIRED_PREFIX + orderId);
            if(date != null && date instanceof Date){
                Date expired = (Date)date;
                if(System.currentTimeMillis() > expired.getTime()){
                    json.put("result", "3");
                    return json.toJSONString();
                }
            }

            validate(order, command, true);

            //风控校验
            riskControlCheck(order);

            long timeout = makeScanUrlRepeat(order, command);

            json.put("url", order.getRemark2());
            json.put("timeout", timeout);

        } catch (Exception e){
            e.printStackTrace();
            json.put("result", "2");
            //add by zhaojt : 目前民生扫码渠道不支持重复订单提交，假刷新，前端使用默认超时时间倒计时。
            json.put("timeout", expiredTime);
            if (e instanceof  GopayException) {
                String code = ((GopayException) e).getErrCode();
                String msg = dicProcCodeService.getProcCodeInfo(code).getMessage();
                String errMsg = ((GopayException) e).getErrMsg();
                if (StringUtils.isBlank(code) && StringUtils.isNotBlank(errMsg)) {
                    json.put("msg", errMsg);
                } else {
                    json.put("msg",(msg == null || "".equals(msg)) ? "内部系统异常" : msg);
                }
            } else {
                json.put("msg", "内部系统异常");
            }
        }
        logger.info("刷新二维码 返回数据：" + json.toJSONString());
        return json.toJSONString();
    }

    /**
     * 生成二维码图片
     * @param order
     */
    private void makeScanUrl(CpsGenMainOrder order, ScanPayCommand command) throws GopayException {

        logger.info("新生成二维码：orderId=" + order.getGopayOrderId());
        //组装bis报文

        updateOrder(order, command, false);
        String url = buildScanPayBisMessage(order, command);

        //计算扫码订单过期时间  6分钟后
        Date expired = DateUtils.add(new Date(), Calendar.MINUTE, 6);
        logger.info("扫码订单将在 " + new SimpleDateFormat("yyyyMMdd HH:mm:ss").format(expired) + " 后 失效!");
        getRequest().getSession().setAttribute(ORDER_EXPIRED_PREFIX+order.getGopayOrderId(), expired);

        order.setRemark2(url);
        updateOrder(order, command, true);

    }

    /**
     * 重新刷新 二维码
     * @param order
     * @param command
     * @return
     * @throws GopayException
     */
    private long makeScanUrlRepeat(CpsGenMainOrder order, ScanPayCommand command) throws GopayException {

        logger.info("刷新二维码：orderId=" + order.getGopayOrderId());
        long timeout = expiredTime;
        Date lastUpdTs = order.getLastUpdTs();
        //获取时间差值
        long diff = System.currentTimeMillis() - lastUpdTs.getTime();
        logger.error("diff==" + diff);
        if (diff >  expiredTime * 1000) {
            //重新生成  二维码
            //组装bis报文
            String url = buildScanPayBisMessage(order, command);
            order.setRemark2(url);

            //更新订单 -- 只更新【更新时间  和 remark1】
            updateOrder(order, command, true);
            timeout = expiredTime;
        } else {
            //减去差值 因为是倒计时
            timeout = expiredTime -  diff / 1000;
            logger.info("在指定时间内不刷新二维码orderId=" + order.getGopayOrderId() + ",timeout=" + timeout);
        }
        return timeout;
    }

}
